<?php

namespace Frieza\Modules\ContentPool\Controllers;

use App\Exceptions\InputErrorException;
use App\Http\Controllers\Controller;
use App\Pockets\GridDataModel as pGridDataModel;
use Doraemon\model\Position\PositionRules;
use Doraemon\pockets\excel\DownExcel;
use Doraemon\pockets\excel\ReadExcel;
use Doraemon\service\ContentPool\ContentPool as sContentPool;
use Doraemon\model\ContentPool\ContentPool as mContentPool;
use Doraemon\service\ContentPool\ContentPoolObjInfo as sContentPoolObjInfo;
use Doraemon\service\position\AdmOperationModule;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Widgets\Form;
use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;

class ContentPoolController extends Controller
{

    public function index(Content $content, Request $request)
    {
        $page = $request->input('page', 1);
        $pageSize = $request->input('per_page', 15);
        $poolList = sContentPool::getPoolList($page, $pageSize);
        return $content->body($this->formatGrid($poolList))
            ->header('内容池管理')
            ->breadcrumb(['text' => '内容池管理']);
    }

    private function formatGrid($poolList)
    {
        $gridModel = new pGridDataModel($poolList['list'], $poolList['total'], [
            'perPage' => $poolList['pageSize']
        ]);
        return Admin::grid($gridModel, function (Grid $grid) {

            $grid->disableFilter();
            $grid->disableExport();
            $grid->disableRowSelector();

            $grid->column('id', '实验Id');
            $grid->column('title', '任务名称');
            $grid->column('user_profile', '用户分群')->width(500)->userProfile();
            $grid->column('start_time', '开始时间')->display(function ($startTime) {
                if (empty($startTime)) {
                    return '未添加开始时间';
                }
                return date('Y-m-d', $startTime);
            });
            $grid->column('obj_count', '包含内容数');
            $grid->column('adminer', '创建者')->display(function ($adminer) {
                return Admin::user()->find($adminer)->name;
            });

            $grid->tools(function (Grid\Tools $tools) {
                $tools->append("<a href='/admin/contentPool/down' class='btn button-success'><i class='fa fa-file-excel-o'></i>>导出模板</a>");
            });
        });
    }

    public function create(Content $content, $poolId = null)
    {
        return $content
            ->header('内容池编辑')
            ->breadcrumb(['text' => '内容池管理', 'url' => 'contentPool'], ['text' => '内容池编辑'])
            ->row($this->formatForm($poolId));
    }

    private function formatForm($poolId)
    {
        $poolInfo = [];
        if ($poolId) {
            $poolInfo = mContentPool::getContentPool($poolId);
            $poolInfo['user_profile'] = AdmOperationModule::getPositionRulesById($poolId, PositionRules::MODULE_TYPE_NEW_USER_CONTENT_POOL, true);
        }
        $form = new Form($poolInfo);
        $form->hidden('pool_id', '内容池id')->default($poolId);
        $form->text('title', '任务名称')->required();
        $form->textarea('remark', '任务概述')->required();
        if (isset($poolId)) {
            $form->display('start_time', '开始时间')->help('开始时间不允许修改')->with(function ($value) {
                return date('Y-m-d', $value);
            });
        } else {
            $form->date('start_time', '开始时间')->required()->help('开始时间不允许修改');
        }
        $form->rate('proportion', '人工内容比重')->width(20)->help('单位为%');
        $form->file('excel', '上传objId')->removable()->help('仅支持"xls"文件,并请按照模板格式填写')->rules('mimes:xls,xlsx');
        $form->userProfile('user_profile', '用户分群')->generate();
        $form->action('/admin/contentPool/save');
        return $form->render();
    }

    public function save(Request $request)
    {
        $params = $request->all();
        $poolData = [
            'title' => $params['title'],
            'remark' => $params['remark'],
            'proportion' => $params['proportion']
        ];
        $data = $this->checkData($params);
        if (!empty($params['pool_id'])) {
            mContentPool::update($poolData, ['id' => $params['pool_id']]);
            $rs = $params['pool_id'];
            AdmOperationModule::addUserProfile($rs, $params['user_profile'], PositionRules::MODULE_TYPE_NEW_USER_CONTENT_POOL);
        } else {
            $poolData['addtime'] = time();
            $poolData['task_status'] = mContentPool::STATUS_NORMAL;
            $poolData['adminer'] = Admin::user()->id;
            $poolData['start_time'] = strtotime($params['start_time']);
            $rs = mContentPool::insertPoolData($poolData);
            if (!$rs) {
                throw new \Exception('插入异常');
            } else {
                AdmOperationModule::addUserProfile($rs, $params['user_profile'], PositionRules::MODULE_TYPE_NEW_USER_CONTENT_POOL);
            }
        }
        return sContentPoolObjInfo::insertObjInfos($rs, $data, Admin::user()->id);
    }

    /**
     * @throws InputErrorException
     * @throws \Exception
     */
    private function checkData($params)
    {
        $data = [];
        if (mb_strlen($params['title']) > 99) {
            throw new InputErrorException('标题最大长度为15', InputErrorException::DEFAULT_CODE, 'title');
        }

        if (mb_strlen($params['remark']) > 50) {
            throw new InputErrorException('概述最大长度为50', InputErrorException::DEFAULT_CODE, 'remark');
        }

        if ($params['proportion'] < 0 || $params['proportion'] > 100) {
            throw new InputErrorException('比重异常，请重新输入', InputErrorException::DEFAULT_CODE, 'proportion');
        }

        if (!isset($params['excel'])) {
            throw new InputErrorException('文件不存在', InputErrorException::DEFAULT_CODE, 'excel');
        }

        if (!strpos($params['excel']->getClientOriginalName(), '.xls')) {
            throw new InputErrorException('文件格式不符！', InputErrorException::DEFAULT_CODE, 'excel');
        }

        try {
            $newFileName = 'contentPool-' . date('YmdHis') . '.xls';
            $newFilePath = '/tmp' . '/' . $newFileName;
            $rs = move_uploaded_file($params['excel'], $newFilePath);
            if (!$rs) {
                throw new \Exception();
            }
            $excel = new ReadExcel($newFileName);
            $excelData = $excel->getExcelDataNoHeader($newFilePath);
        } catch (\Exception $e) {
            throw new InputErrorException('文件上传失败', InputErrorException::DEFAULT_CODE, 'excel');
        }

        $excelKeyArray = ['obj_id', 'score'];
        $iMax = count($excelData);
        for ($i = 1; $i < $iMax; $i++) {
            $excelData[$i] = array_slice($excelData[$i], 0, count($excelKeyArray));
            $singleData = array_combine($excelKeyArray, $excelData[$i]);
            if (is_null($singleData['obj_id']) || is_null($singleData['score'])) {
                break;
            }
            if (!self::checkObjId($singleData['obj_id'])) {
                $error = new MessageBag([
                    'title' => '在操作' . $singleData['obj_id'] . '时失败,格式错误'
                ]);
                return back()->with(compact('error'));
            }
            $data[] = $singleData;
        }
        return $data;
    }

    public function delete($id)
    {
        return sContentPool::bothDelete($id, Admin::user()->id);
    }

    public function down()
    {
        $downExcel = new DownExcel();
        $title = '内容池模板';
        $downExcel->setFrontBold('1');
        $downExcel->setFileName($title);
        $downExcel->setTitle($title);
        $downExcel->setSheetTitle($title);
        $data = [
            0 => ['例:0056qs800003facz', '1']
        ];
        $head = [
            'obj_id', '权重',
        ];
        $downExcel->create($data, $head);
        return back();
    }

    private static function checkObjId($obj_id)
    {
        return preg_match('/^[0-9a-z]{16}$/i', $obj_id);
    }
}